using System;
using System.Collections.Generic;
using System.Reflection;
using System.Web;
using System.Web.Profile;
using System.Web.Security;

using MettleSystems.dashCommerce.Core;
using MettleSystems.dashCommerce.Core.Caching;
using MettleSystems.dashCommerce.Store;
using MettleSystems.dashCommerce.Controls;
using OpenNetCommerce.Localization;

namespace MettleSystems.dashCommerce.Web
{
	public class Global : WebApplicationBase
	{
		/// <summary>
		/// Handles the Start event of the Application control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
		override protected void Application_Start(object sender, EventArgs e)
		{
			OpenNetCommerce.Localization.MacroSystem.Macros = PredefMacros;

			base.Application_Start(sender, e);
		}

		/// <summary>
		/// Handles the End event of the Application control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
		protected void Application_End(object sender, EventArgs e)
		{
		}

		protected void Application_Error(object sender, EventArgs e)
		{
			// Code that runs when an unhandled error occurs
			Logger.LogMessageType msgType = Logger.LogMessageType.Error;
			Exception exAppError = Server.GetLastError();
			bool logException = true;
			Exception baseException = exAppError.GetBaseException();
			if (baseException is System.Data.SqlClient.SqlException && baseException.Message.StartsWith("Timeout expired")) {
				msgType = Logger.LogMessageType.DatabaseError; //Database timeout error.
			}
			else if (baseException is System.Web.HttpException && baseException.Message.EndsWith("does not exist.")) {
				msgType = Logger.LogMessageType.Warning; //404 Errors not really and error but might be usefull to log them.
			}
			else if (baseException is System.Security.Cryptography.CryptographicException && baseException.Message.StartsWith("Padding is invalid")) {
				logException = false; //Googlebots can fire these exceptions it's safe to ignore them.
			}
			if (logException)
				Logger.Error(exAppError.Message, exAppError, msgType);
		}

		/// <summary>
		/// Handles the PreRequestHandlerExecute event of the Application control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
		protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
		{
			/* getting the site settings is not required; it is a singleton gotten automatically
			SiteSettings siteSettings = null;
			try {
				siteSettings = SiteSettingCache.GetSiteSettings();
			}
			catch (Exception) {
				//swallow it - probably no connection string during install
			}*/

			string cultureName = "en-US"; //default this. TODO: Get this into installer?
			if (SiteSettings != null) {
				cultureName = SiteSettings.Language ?? cultureName;
			}
			System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture(cultureName);
			System.Threading.Thread.CurrentThread.CurrentUICulture = System.Threading.Thread.CurrentThread.CurrentCulture;
		}

		/// <summary>
		/// Handles the OnMigrateAnonymous event of the Profile control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="args">The <see cref="T:System.Web.Profile.ProfileMigrateEventArgs"/> instance containing the event data.</param>
		public void Profile_OnMigrateAnonymous(object sender, ProfileMigrateEventArgs args)
		{
			OrderController.MigrateCart(args.AnonymousID, WebProfile.Current.UserName);
			ProfileManager.DeleteProfile(args.AnonymousID);
			AnonymousIdentificationModule.ClearAnonymousIdentifier();
		}

		#region Predefined macros

		private static readonly Dictionary<string, Func<string>> PredefMacros
			= new Dictionary<string, Func<string>>()
			  	{
					{"CurrentDate", () => DateTime.Now.Date.ToShortDateString()},
					{"CurrentTime", () => DateTime.Now.TimeOfDay.ToString()},
			  		{"ProductName", () => ProductName},
			  		{"SiteName", () => SiteSettings.SiteName},
					{"PageLocalizedTitle", () => LocalizationUtility.GetText((HttpContext.Current.Handler as BasePage).LocalizedTitleKey)}
			  	};

		#endregion
	}
}